package com.ynet.middleground.riskmanage.model.hangxin;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;

import javax.xml.bind.JAXBException;

import com.ynet.middleground.riskmanage.dto.hangxin.respxml.invoiceResult.FPXX;
import com.ynet.middleground.riskmanage.dto.rizhaogang.RizhaoPortDockCompanyInfoDTO;
import com.ynet.middleground.riskmanage.utils.BeanUtil;
import org.apache.commons.lang3.StringUtils;
import org.dozer.Mapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.ynet.core.exception.BusinessException;
import com.ynet.core.log.IfpLogger;
import com.ynet.middleground.riskmanage.bean.hangxin.*;
import com.ynet.middleground.riskmanage.bean.hangxin.hzfpsqdsq.INPUT;
import com.ynet.middleground.riskmanage.common.SystemConstant;
import com.ynet.middleground.riskmanage.dto.hangxin.*;
import com.ynet.middleground.riskmanage.dto.hangxin.respxml.commomResp.CommonOutput;
import com.ynet.middleground.riskmanage.dto.hangxin.respxml.dlsb.FPXTOUTPUT;
import com.ynet.middleground.riskmanage.dto.hangxin.respxml.hzfpsqdsc.DATA;
import com.ynet.middleground.riskmanage.dto.hangxin.respxml.ykccx.FPKC;
import com.ynet.middleground.riskmanage.dto.hangxin.respxml.ykccx.OUTPUT;
import com.ynet.middleground.riskmanage.external.hangxin.HangXinUriEnum;
import com.ynet.middleground.riskmanage.utils.WebServiceUtil;
import com.ynet.middleground.riskmanage.utils.XStreamUtil;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

/**
 * @author liwq
 * @description 航信model层
 * @date 2021/11/8 17:29
 */
@Component
public class HxModel {

    public static final String success_code = "000000";
    final BASE64Encoder encoder = new BASE64Encoder();
    final BASE64Decoder decoder = new BASE64Decoder();

    @Autowired
    private Mapper dozerBeanMapper;

    @Autowired
    private WebServiceUtil webServiceUtil;

    /**
     * 云库存查询
     *
     * @param req
     * @return
     */
    public List<YkccxDTO> ykccx(YkccxReq req) {
        // step1: 整理请求信息
        String reqDataXML = XStreamUtil.objectToXml(req, "");
        IfpLogger.info(Thread.currentThread().getStackTrace()[1].getMethodName(), "云库存查询加密前Data: {}", reqDataXML);
        String reqDataXMLEncoder = WebServiceUtil.base64Encoder(reqDataXML);

        // step2: 转调航信
        String respXML = webServiceUtil.HxWebUtil(HangXinUriEnum.YKCCX, reqDataXMLEncoder, req, "");

        // step3: 整理结果并返回
        CommonOutput commonOutput = XStreamUtil.converyToJavaBean(respXML, CommonOutput.class);
        String code = commonOutput.getCode();
        String mess = commonOutput.getMess();
        if (!success_code.equals(code)) {
            throw new BusinessException(mess, code);
        }
        // 加密的Data
        String respData = commonOutput.getData();
        // 解密Data
        respData = WebServiceUtil.base64Decoder(respData);
        IfpLogger.info(Thread.currentThread().getStackTrace()[1].getMethodName(), "云库存查询返回信息Data解密后: {}", respData);
        OUTPUT respYkccx = XStreamUtil.converyToJavaBean(respData, OUTPUT.class);
        // 封装返回对象
        List<FPKC> fpkcs = respYkccx.getData().getFpkcs().getFpkc();
        List<YkccxDTO> ykccxDTOs = null;
        if (fpkcs != null && fpkcs.size() > 0) {
            ykccxDTOs = BeanUtil.mapList(dozerBeanMapper, fpkcs, YkccxDTO.class);
        }
        return ykccxDTOs;
    }

    /**
     * 红字发票申请单申请
     *
     * @param req
     * @return
     */
    public String hzfpsqdsq(INPUT req) throws UnsupportedEncodingException {
        // step1: 整理请求信息
        String reqXML = XStreamUtil.objectToXml(req, "");
        IfpLogger.info(Thread.currentThread().getStackTrace()[1].getMethodName(), "红字发票申请单申请加密前Data: {}", reqXML);
        String reqDataXMLEncoder = WebServiceUtil.base64Encoder(reqXML);

        // step2: 转调航信
        String respXML = webServiceUtil.HxWebUtil(HangXinUriEnum.HZFPSQDSQ, reqDataXMLEncoder, req, "");

        // step3: 整理结果并返回
        CommonOutput commonOutput = XStreamUtil.converyToJavaBean(respXML, CommonOutput.class);
        String code = commonOutput.getCode();
        String mess = commonOutput.getMess();
        if (!success_code.equals(code)) {
            throw new BusinessException(mess, code);
        }
        // 加密的Data
        String respData = commonOutput.getData();
        // 解密Data
        respData = WebServiceUtil.base64Decoder(respData);
        IfpLogger.info(Thread.currentThread().getStackTrace()[1].getMethodName(), "红字发票申请单申请返回信息Data解密后: {}", respData);
        com.ynet.middleground.riskmanage.dto.hangxin.respxml.hzfpsqdsq.OUTPUT output = XStreamUtil
            .converyToJavaBean(respData, com.ynet.middleground.riskmanage.dto.hangxin.respxml.hzfpsqdsq.OUTPUT.class);
        String xxblsh = output.getData().getXxblsh();
        return xxblsh;
    }

    /**
     * 红字发票申请单上传
     *
     * @param req
     * @return
     */
    public HzfpsqdscDTO hzfpsqdsc(HzfpsqdscReq req) {
        // step1: 整理请求信息
        String reqXML = XStreamUtil.objectToXml(req, "");
        IfpLogger.info(Thread.currentThread().getStackTrace()[1].getMethodName(), "红字发票申请单上传请求信息Data加密前: {}", reqXML);
        String reqDataXMLEncoder = WebServiceUtil.base64Encoder(reqXML);

        // step2: 转调航信
        String respXML = webServiceUtil.HxWebUtil(HangXinUriEnum.HZFPSQDSC, reqDataXMLEncoder, req, "");

        // step3: 整理结果并返回
        CommonOutput commonOutput = XStreamUtil.converyToJavaBean(respXML, CommonOutput.class);
        String code = commonOutput.getCode();
        String mess = commonOutput.getMess();
        if (!success_code.equals(code)) {
            throw new BusinessException(mess, code);
        }
        // 加密的Data
        String respData = commonOutput.getData();
        // 解密Data
        respData = WebServiceUtil.base64Decoder(respData);
        IfpLogger.info(Thread.currentThread().getStackTrace()[1].getMethodName(), "红字发票申请单上传响应信息Data解密后: {}", respData);
        com.ynet.middleground.riskmanage.dto.hangxin.respxml.hzfpsqdsc.OUTPUT output = XStreamUtil
            .converyToJavaBean(respData, com.ynet.middleground.riskmanage.dto.hangxin.respxml.hzfpsqdsc.OUTPUT.class);
        HzfpsqdscDTO hzfpsqdscReq = null;
        DATA data = output.getData();
        if (data != null) {
            hzfpsqdscReq = new HzfpsqdscDTO();
            hzfpsqdscReq.setNsrsbh(data.getNsrsbh());
            hzfpsqdscReq.setFjh(data.getFjh());
            hzfpsqdscReq.setYwlsh(data.getYwlsh());
        }
        return hzfpsqdscReq;
    }

    /**
     * 红字发票申请单撤销
     *
     * @param req
     * @return
     */
    public HzfpsqdcxDTO hzfpsqdcx(HzfpsqdcxReq req) {
        // step1: 整理请求信息
        String reqXML = XStreamUtil.objectToXml(req, "");
        IfpLogger.info(Thread.currentThread().getStackTrace()[1].getMethodName(), "红字发票申请单撤销请求信息Data加密前: {}", reqXML);
        String reqDataXMLEncoder = WebServiceUtil.base64Encoder(reqXML);

        // step2: 转调航信
        String respXML = webServiceUtil.HxWebUtil(HangXinUriEnum.HZFPSQDCX, reqDataXMLEncoder, req, "");

        // step3: 整理结果并返回
        CommonOutput commonOutput = XStreamUtil.converyToJavaBean(respXML, CommonOutput.class);
        String code = commonOutput.getCode();
        String mess = commonOutput.getMess();
        if (!success_code.equals(code)) {
            throw new BusinessException(mess, code);
        }
        // 加密的Data
        String respData = commonOutput.getData();
        // 解密Data
        respData = WebServiceUtil.base64Decoder(respData);
        IfpLogger.info(Thread.currentThread().getStackTrace()[1].getMethodName(), "红字发票申请单撤销响应信息Data解密后: {}", respData);
        com.ynet.middleground.riskmanage.dto.hangxin.respxml.hzfpsqdcx.OUTPUT output = XStreamUtil
            .converyToJavaBean(respData, com.ynet.middleground.riskmanage.dto.hangxin.respxml.hzfpsqdcx.OUTPUT.class);
        // step3: 整理结果并返回
        com.ynet.middleground.riskmanage.dto.hangxin.respxml.hzfpsqdcx.DATA data = null;
        HzfpsqdcxDTO hzfpsqdcxDTO = null;
        data = output.getData();
        if (data != null) {
            hzfpsqdcxDTO = new HzfpsqdcxDTO();
            hzfpsqdcxDTO.setNsrsbh(data.getNsrsbh());
            hzfpsqdcxDTO.setFjh(data.getFjh());
            hzfpsqdcxDTO.setYwlsh(data.getYwlsh());
        }
        return hzfpsqdcxDTO;
    }

    /**
     * 红字发票申请单下载
     *
     * @param req
     * @return
     */
    public HzfpsqdxzDTO hzfpsqdxz(HzfpsqdxzReq req) {
        // step1: 整理请求信息
        String reqXML = XStreamUtil.objectToXml(req, "");
        IfpLogger.info(Thread.currentThread().getStackTrace()[1].getMethodName(), "红字发票申请单下载请求信息Data加密前: {}", reqXML);
        String reqDataXMLEncoder = WebServiceUtil.base64Encoder(reqXML);

        // step2: 转调航信
        String respXML = webServiceUtil.HxWebUtil(HangXinUriEnum.HZFPSQDXZ, reqDataXMLEncoder, req, "");

        // step3: 整理结果并返回
        CommonOutput commonOutput = XStreamUtil.converyToJavaBean(respXML, CommonOutput.class);
        String code = commonOutput.getCode();
        String mess = commonOutput.getMess();
        if (!success_code.equals(code)) {
            throw new BusinessException(mess, code);
        }
        // 加密的Data
        String respData = commonOutput.getData();
        // 解密Data
        respData = WebServiceUtil.base64Decoder(respData);
        IfpLogger.info(Thread.currentThread().getStackTrace()[1].getMethodName(), "红字发票申请单下载响应信息Data解密后: {}", respData);
        com.ynet.middleground.riskmanage.dto.hangxin.respxml.hzfpsqdxz.OUTPUT output = XStreamUtil
            .converyToJavaBean(respData, com.ynet.middleground.riskmanage.dto.hangxin.respxml.hzfpsqdxz.OUTPUT.class);
        HzfpsqdxzDTO hzfpsqdxzDTO = null;
        com.ynet.middleground.riskmanage.dto.hangxin.respxml.hzfpsqdxz.DATA data = null;
        data = output.getData();
        if (data != null) {
            hzfpsqdxzDTO = new HzfpsqdxzDTO();
            hzfpsqdxzDTO.setNsrsbh(data.getNsrsbh());
            hzfpsqdxzDTO.setFjh(data.getFjh());
            hzfpsqdxzDTO.setYwlsh(data.getYwlsh());
        }
        return hzfpsqdxzDTO;
    }

    /**
     * 税控业务操作处理结果查询
     *
     * @param req
     * @return
     */
    public OperationResultQueryDTO operationResultQuery(OperationResultQueryReq req) {
        // step1: 整理请求信息
        String reqXML = XStreamUtil.objectToXml(req, "");
        IfpLogger.info(Thread.currentThread().getStackTrace()[1].getMethodName(), "税控业务操作处理结果查询请求信息Data加密前: {}",
            reqXML);

        String reqDataXMLEncoder = WebServiceUtil.base64Encoder(reqXML);

        // step2: 转调航信
        String respXML = webServiceUtil.HxWebUtil(HangXinUriEnum.OPERATIONRESULTQUERY, reqDataXMLEncoder, req, "");

        // step3: 整理结果并返回
        CommonOutput commonOutput = XStreamUtil.converyToJavaBean(respXML, CommonOutput.class);
        String code = commonOutput.getCode();
        String mess = commonOutput.getMess();
        if (!success_code.equals(code)) {
            throw new BusinessException(mess, code);
        }
        // 加密的Data
        String respData = commonOutput.getData();
        // 解密Data
        respData = WebServiceUtil.base64Decoder(respData);
        IfpLogger.info(Thread.currentThread().getStackTrace()[1].getMethodName(), "税控业务操作处理结果查询响应信息Data解密后: {}",
            respData);
        com.ynet.middleground.riskmanage.dto.hangxin.respxml.operationResultQuery.OUTPUT output =
            XStreamUtil.converyToJavaBean(respData,
                com.ynet.middleground.riskmanage.dto.hangxin.respxml.operationResultQuery.OUTPUT.class);
        OperationResultQueryDTO o = null;
        com.ynet.middleground.riskmanage.dto.hangxin.respxml.operationResultQuery.DATA data = null;
        data = output.getData();
        if (data != null) {
            o = new OperationResultQueryDTO();
            o.setNsrsbh(data.getNsrsbh());
            o.setFjh(data.getFjh());
            o.setYwlsh(data.getYwlsh());
            o.setYwjgdm(data.getYwjgdm());
            o.setYwjgms(data.getYwjgms());
            o.setYwlx(data.getYwlx());
            o.setTssj(data.getTssj());
            o.setByzd1(data.getByzd1());
            o.setByzd2(data.getByzd2());
            o.setByzd3(data.getByzd3());
        }
        return o;
    }

    /**
     * 查询开票结果
     *
     * @param req
     * @auther songyf
     */
    public List<InvoiceResultDTO> queryInvoiceResult(QueryInvoiceResultReq req) throws IOException {
        String reqXML = XStreamUtil.objectToXml(req, "");
        IfpLogger.info(Thread.currentThread().getStackTrace()[1].getMethodName(), "查询开票结果请求信息Data加密前: {}", reqXML);
        String reqText = WebServiceUtil.base64Encoder(reqXML);
        // 转调航信
        String respXML = webServiceUtil.HxWebUtil(HangXinUriEnum.YFPCX, reqText, req, "");
        // 整理结果并返回
        CommonOutput commonOutput = XStreamUtil.converyToJavaBean(respXML, CommonOutput.class);
        String code = commonOutput.getCode();
        String mess = commonOutput.getMess();
        if (!success_code.equals(code)) {
            throw new BusinessException(mess, code);
        }
        // 加密的Data
        String respData = commonOutput.getData();
        // 解密Data
        respData = WebServiceUtil.base64Decoder(respData);
        // String respData = "<?xml version=\"1.0\" encoding=\"GBK\"?>\n" + "<OUTPUT>\n" + " <CODE>000000</CODE>\n"
        // + " <MESS></MESS>\n" + " <DATA>\n" + " <FPXXS>\n" + " <FPXX index=\"1\">\n"
        // + " <FPLSH>发票流水号</FPLSH>\n" + " <FPQQLSH>发票流水号</FPQQLSH>\n"
        // + " <FPDM>发票代码</FPDM>\n" + " <FPHM>发票号码</FPHM>\n"
        // + " <FPLX>开票类型</FPLX>\n" + " <KPSJ>开票时间</KPSJ>\n"
        // + " <PDF>PDF路径</PDF>\n" + " <FPMW>发票密文</FPMW>\n"
        // + " <XFSH>销方税号</XFSH>\n" + " <XFMC>销方名称</XFMC>\n"
        // + " <XFDZDH>销方地址电话</XFDZDH>\n" + " <XFYHZH>销方银行账号</XFYHZH>\n"
        // + " <GFSH>购方税号</GFSH>\n" + " <GFMC>购方名称</GFMC>\n"
        // + " <GFDZDH>购方地址电话</GFDZDH>\n" + " <GFYHZH>购方银行账号</GFYHZH>\n"
        // + " <HJJE>合计金额（不含税）</HJJE>\n" + " <HJSE>合计税额</HJSE>\n"
        // + " <HJHSJE>价税合计</HJHSJE>\n" + " <BZ>备注</BZ>\n"
        // + " <SKR>收款人</SKR>\n" + " <KPR>开票人</KPR>\n"
        // + " <FHR>复核人</FHR>\n" + " <JYM>校验码</JYM>\n"
        // + " <YFPDM>原发票代码</YFPDM>\n" + " <YFPHM>原发票号码</YFPHM>\n"
        // + " <HPTZDBH>红票通知单编号</HPTZDBH>\n" + " <FPMXS>\n"
        // + " <FPMX>\n" + " <SPMC>商品名称</SPMC>\n"
        // + " <GGXH>规格型号</GGXH>\n" + " <JLDW>单位</JLDW>\n"
        // + " <DJ>不含税单价</DJ>\n" + " <SL>数量</SL>\n"
        // + " <JE>金额</JE>\n" + " <SLV>税率</SLV>\n"
        // + " <SE>税额</SE>\n" + " <HSDJ>含税单价</HSDJ>\n"
        // + " <HSJE>含税金额</HSJE>\n" + " <SSFLBM>商品编码</SSFLBM>\n"
        // + "\t\t\t\t\t\t<YHZCBS>1</YHZCBS>\n" + " <YHZCSM>优惠政策内容</YHZCSM>\n"
        // + " <LSLBS>零税率标识</LSLBS>\n" + " </FPMX>\n" + " </FPMXS>\n"
        // + " </FPXX>\n" + " <FPXX index=\"2\">\n" + " <FPLSH>发票流水号</FPLSH>\n"
        // + " <FPQQLSH>发票流水号</FPQQLSH>\n" + " <FPDM>发票代码</FPDM>\n"
        // + " <FPHM>发票号码</FPHM>\n" + " <FPLX>开票类型</FPLX>\n"
        // + " <KPSJ>开票时间</KPSJ>\n" + " <PDF>PDF路径</PDF>\n"
        // + " <FPMW>发票密文</FPMW>\n" + " <XFSH>销方税号</XFSH>\n"
        // + " <XFMC>销方名称</XFMC>\n" + " <XFDZDH>销方地址电话</XFDZDH>\n"
        // + " <XFYHZH>销方银行账号</XFYHZH>\n" + " <GFSH>购方税号</GFSH>\n"
        // + " <GFMC>购方名称</GFMC>\n" + " <GFDZDH>购方地址电话</GFDZDH>\n"
        // + " <GFYHZH>购方银行账号</GFYHZH>\n" + " <HJJE>合计金额（不含税）</HJJE>\n"
        // + " <HJSE>合计税额</HJSE>\n" + " <HJHSJE>价税合计</HJHSJE>\n"
        // + " <BZ>备注</BZ>\n" + " <SKR>收款人</SKR>\n" + " <KPR>开票人</KPR>\n"
        // + " <FHR>复核人</FHR>\n" + " <JYM>校验码</JYM>\n"
        // + " <YFPDM>原发票代码</YFPDM>\n" + " <YFPHM>原发票号码</YFPHM>\n"
        // + " <HPTZDBH>红票通知单编号</HPTZDBH>\n" + " <FPMXS>\n"
        // + " <FPMX>\n" + " <SPMC>商品名称</SPMC>\n"
        // + " <GGXH>规格型号</GGXH>\n" + " <JLDW>单位</JLDW>\n"
        // + " <DJ>不含税单价</DJ>\n" + " <SL>数量</SL>\n"
        // + " <JE>金额</JE>\n" + " <SLV>税率</SLV>\n"
        // + " <SE>税额</SE>\n" + " <HSDJ>含税单价</HSDJ>\n"
        // + " <HSJE>含税金额</HSJE>\n" + " <SSFLBM>商品编码</SSFLBM>\n"
        // + "\t\t\t\t\t\t<YHZCBS>1</YHZCBS>\n" + " <YHZCSM>优惠政策内容</YHZCSM>\n"
        // + " <LSLBS>零税率标识</LSLBS>\n" + " </FPMX>\n" + " </FPMXS>\n"
        // + " </FPXX>\n" + " </FPXXS>\n" + "</DATA></OUTPUT>\n";
        IfpLogger.info(Thread.currentThread().getStackTrace()[1].getMethodName(), "查询开票结果响应信息Data解密后: {}", respData);
        com.ynet.middleground.riskmanage.dto.hangxin.respxml.invoiceResult.OUTPUT respOutPut =
            XStreamUtil.converyToJavaBean(respData,
                com.ynet.middleground.riskmanage.dto.hangxin.respxml.invoiceResult.OUTPUT.class);
        // 整理结果并返回
        List<InvoiceResultDTO> invoiceResultDTOs = new ArrayList<>();
        List<FPXX> fPXX = respOutPut.getData().getFpxxs().getFpxx();
        if (fPXX != null) {
            invoiceResultDTOs = BeanUtil.mapList(dozerBeanMapper, fPXX, InvoiceResultDTO.class);
        }
        System.out.println("响应信息:" + invoiceResultDTOs.toString());
        return invoiceResultDTOs;
    }

    /**
     * @param req
     * @return
     * @throws JAXBException
     * @auth songyj
     * @desc 发票开具
     */
    public InvoiceIssuedDTO invoiceIssued(InvoiceIssuedReq req) throws Exception {
        GetToken getToken = dozerBeanMapper.map(req, GetToken.class);
        getToken.setSh(req.getQysh());
        getToken.setZfjh(req.getZfjh());
        String tokenXML = XStreamUtil.objectToXml(getToken, "");

        // step1：获取Token秘钥
        String resptokenXML =
            webServiceUtil.HxWebUtil(HangXinUriEnum.DLSB, WebServiceUtil.base64Encoder(tokenXML), req, "");
        FPXTOUTPUT fpxt = XStreamUtil.converyToJavaBean(resptokenXML, FPXTOUTPUT.class);
        String code = fpxt.getCODE();
        String mess = fpxt.getMESS();
        if (!success_code.equals(code)) {
            throw new BusinessException(mess, code);
        }
        // 取出加密用的秘钥
        String token = fpxt.getDATA();
        IfpLogger.info(Thread.currentThread().getStackTrace()[1].getMethodName(), "发票开具获取的Token秘钥: {}", token);

        // Step2: 组装开票请求信息：Data
        String reqXML = XStreamUtil.objectToXml(req, "FPKJINPUT");
        IfpLogger.info(Thread.currentThread().getStackTrace()[1].getMethodName(), "发票开具请求信息Data加密前: {}", reqXML);
        // 税号和具体Data先3des加密，然后base64加密
        String reqText = WebServiceUtil.threeDesAndBase64(token, reqXML);
        String shmw = WebServiceUtil.threeDesAndBase64(token, req.getQysh());

        // step3: 发送请求
        String respXML = webServiceUtil.HxWebUtil(HangXinUriEnum.YFPKJ, reqText, req, shmw);
        // String respXML =
        // "<?xml version=\"1.0\"
        // encoding=\"GBK\"?><FPXT_OUTPUT><ID>YFPKJ</ID><DATA>PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iR0JLIj8+PEZQS0pPVVRQVVQ+PE9VVFBVVD48SUQ+RlBLSjwvSUQ+PENPREU+MTAwMDwvQ09ERT48TUVTUz5INcrcwO2zybmmLLWlvt3W2Li0t6LLzTwvTUVTUz48REFUQT48RlBRUUxTSD4yMDIxMTIyMTYzNzM3OTk1NDY8L0ZQUVFMU0g+PC9EQVRBPjwvT1VUUFVUPjwvRlBLSk9VVFBVVD4=</DATA><CODE>000000</CODE></FPXT_OUTPUT>\n";

        // step4：整理结果并返回
        CommonOutput commonOutput2 = XStreamUtil.converyToJavaBean(respXML, CommonOutput.class);
        String code2 = commonOutput2.getCode();
        String mess2 = commonOutput2.getMess();
        // 加密的Data;开票成功的话，Data必然有数据；失败的话，根据失败原因不同，有可能为null也有可能不为null;
        String respData = commonOutput2.getData();
        // 解密Data
        if (!StringUtils.isEmpty(respData)) {
            respData = WebServiceUtil.base64Decoder(respData);
        }
        IfpLogger.info(Thread.currentThread().getStackTrace()[1].getMethodName(), "发票开具响应信息Data解密: {}", respData);
        // 注意：发票开具成功、失败分别对应两个应答格式，这里要通过CODE判断出成功还是失败，用两套标准去解析XML
        if (success_code.equals(code2)) {
            com.ynet.middleground.riskmanage.dto.hangxin.respxml.invoiceIssued.FPKJOUTPUT respOutPut =
                XStreamUtil.converyToJavaBean(respData,
                    com.ynet.middleground.riskmanage.dto.hangxin.respxml.invoiceIssued.FPKJOUTPUT.class);
            InvoiceIssuedDTO invoiceIssuedDTO = new InvoiceIssuedDTO();
            if (respOutPut.getOutput().getData().getFpqqlsh() != null) {
                invoiceIssuedDTO.setFpqqlsh(respOutPut.getOutput().getData().getFpqqlsh());
            }
            return invoiceIssuedDTO;
        } else {
            // respData = "<?xml version=\"1.0\" encoding=\"GBK\"?>\n" + "<FPKJOUTPUT>\n" + " <OUTPUT>\n"
            // + " <RETURN>\n" + " <CODE>\n" + " 000002\n" + " </CODE>\n"
            // + " <MESS>\n" + " 失败1234556\n" + " </MESS>\n"
            // + " </RETURN>\n" + " <DATA>\n" + " 失败1234556\n" + " </DATA>\n"
            // + " </OUTPUT>\n" + "</FPKJOUTPUT>";
            if (StringUtils.isEmpty(respData)) {
                throw new BusinessException(mess2, code2);
            } else {
                com.ynet.middleground.riskmanage.dto.hangxin.respxml.invoiceIssued.failed.FPKJOUTPUT respOutPut =
                    XStreamUtil.converyToJavaBean(respData,
                        com.ynet.middleground.riskmanage.dto.hangxin.respxml.invoiceIssued.failed.FPKJOUTPUT.class);
                throw new BusinessException(respOutPut.getOutput().get_return().getMess(),
                    respOutPut.getOutput().get_return().getCode());
            }
        }
    }

    /**
     * 打印发票
     *
     * @param req
     * @auther songyf
     */
    public String invoicePrint(InvoicePrintReq req) throws IOException {
        String reqXML = XStreamUtil.objectToXml(req, "");
        String reqText = WebServiceUtil.base64Encoder(reqXML);
        // 请求航信
        String respXML = webServiceUtil.HxWebUtil(HangXinUriEnum.YFPDY, reqText, req, "");
        // 整理结果并返回
        CommonOutput commonOutput = XStreamUtil.converyToJavaBean(respXML, CommonOutput.class);
        String code = commonOutput.getCode();
        String mess = commonOutput.getMess();
        if (!success_code.equals(code)) {
            throw new BusinessException(mess, code);
        }
        String returnResult = SystemConstant.SYSTEM_SUCCESS;
        return returnResult;
    }

    /**
     * 打印发票数据获取
     *
     * @param req
     * @auther songyf
     */
    public InvoicePrintGetDTO invoicePrintGet(InvoicePrintGetReq req) throws IOException {
        String reqXML = XStreamUtil.objectToXml(req, "");
        String reqText = WebServiceUtil.base64Encoder(reqXML);
        IfpLogger.info(Thread.currentThread().getStackTrace()[1].getMethodName(), "打印发票数据获取请求信息Data加密前: {}", reqText);
        // 转调航信
        String respXML = webServiceUtil.HxWebUtil(HangXinUriEnum.YHQFPDYSJ, reqText, req, "");
        // 整理结果并返回
        CommonOutput commonOutput = XStreamUtil.converyToJavaBean(respXML, CommonOutput.class);
        String code = commonOutput.getCode();
        String mess = commonOutput.getMess();
        if (!success_code.equals(code)) {
            throw new BusinessException(mess, code);
        }
        // 加密的Data
        String respData = commonOutput.getData();
        // 解密Data
        respData = WebServiceUtil.base64Decoder(respData);
        IfpLogger.info(Thread.currentThread().getStackTrace()[1].getMethodName(), "打印发票数据获取响应信息Data解密: {}", respData);
        com.ynet.middleground.riskmanage.dto.hangxin.respxml.invoicePrintGet.OUTPUT respOutPut =
            XStreamUtil.converyToJavaBean(respData,
                com.ynet.middleground.riskmanage.dto.hangxin.respxml.invoicePrintGet.OUTPUT.class);
        InvoicePrintGetDTO invoicePrintGetDTO = new InvoicePrintGetDTO();
        com.ynet.middleground.riskmanage.dto.hangxin.respxml.invoicePrintGet.DATA data = respOutPut.getData();
        if (data != null) {
            invoicePrintGetDTO = dozerBeanMapper.map(data, InvoicePrintGetDTO.class);
        }
        return invoicePrintGetDTO;
    }

    /**
     * @param req
     * @return
     * @throws JAXBException
     * @auth songyf
     * @desc 纸票作废
     */
    public String invoiceVoid(YzpzfReq req) throws IOException {
        String reqXML = XStreamUtil.objectToXml(req, "");
        IfpLogger.info(Thread.currentThread().getStackTrace()[1].getMethodName(), "纸票作废请求信息Data加密前: {}", reqXML);
        String reqText = WebServiceUtil.base64Encoder(reqXML);
        // 请求航信
        String respXML = webServiceUtil.HxWebUtil(HangXinUriEnum.YZPZF, reqText, req, "");
        // 整理结果并返回
        CommonOutput commonOutput = XStreamUtil.converyToJavaBean(respXML, CommonOutput.class);
        String code = commonOutput.getCode();
        String mess = commonOutput.getMess();
        // 加密的Data
        String respData = commonOutput.getData();
        // 解密Data
        respData = WebServiceUtil.base64Decoder(respData);
        IfpLogger.info(Thread.currentThread().getStackTrace()[1].getMethodName(), "纸票作废返回信息Data解密后: {}", respData);
        if (!success_code.equals(code)) {
            throw new BusinessException(mess, code);
        }
        String returnResult = SystemConstant.SYSTEM_SUCCESS;
        return returnResult;
    }

    /**
     * @param req
     * @return
     * @throws JAXBException
     * @auth songyf
     * @desc 纸票作废结果查询
     */
    public String invoiceVoidResult(YzpzfcxReq req) throws IOException {
        String reqXML = XStreamUtil.objectToXml(req, "");
        IfpLogger.info(Thread.currentThread().getStackTrace()[1].getMethodName(), "纸票作废结果查询请求信息Data加密前: {}", reqXML);
        String reqText = WebServiceUtil.base64Encoder(reqXML);
        // 请求航信
        String respXML = webServiceUtil.HxWebUtil(HangXinUriEnum.YZPZFCX, reqText, req, "");
        // 整理结果并返回
        CommonOutput commonOutput = XStreamUtil.converyToJavaBean(respXML, CommonOutput.class);
        String code = commonOutput.getCode();
        String mess = commonOutput.getMess();
        // 加密的Data
        String respData = commonOutput.getData();
        // 解密Data
        respData = WebServiceUtil.base64Decoder(respData);
        IfpLogger.info(Thread.currentThread().getStackTrace()[1].getMethodName(), "纸票作废结果查询返回信息Data解密后: {}", respData);
        if (!success_code.equals(code)) {
            throw new BusinessException(mess, code);
        }
        String returnResult = SystemConstant.SYSTEM_SUCCESS;
        return returnResult;
    }

    /**
     * 单据删除
     * 
     * @param req
     * @throws IOException
     */
    public String djsc(InvoiceDeleteReq req) throws IOException {
        String reqXML = XStreamUtil.objectToXml(req, "");
        IfpLogger.info(Thread.currentThread().getStackTrace()[1].getMethodName(), "单据删除请求信息Data加密前: {}", reqXML);
        String reqText = WebServiceUtil.base64Encoder(reqXML);
        // 请求航信
        String respXML = webServiceUtil.HxWebUtil(HangXinUriEnum.DJSC, reqText, req, "");
        // 整理结果并返回
        CommonOutput commonOutput = XStreamUtil.converyToJavaBean(respXML, CommonOutput.class);
        String code = commonOutput.getCode();
        String mess = commonOutput.getMess();
        if (!success_code.equals(code)) {
            throw new BusinessException(mess, code);
        }
        String returnResult = SystemConstant.SYSTEM_SUCCESS;
        return returnResult;
    }
}
